package com.lei.mydb.backend.dm.pageCache;


import com.lei.mydb.backend.dm.page.Page;
import com.lei.mydb.backend.utils.Panic;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

import com.lei.mydb.common.Error;

/**
 * @author lbwxxc
 * @date 2025/4/29 21:33
 * @description: 对数据页管理，读取数据页、回写数据页等
 */
public interface PageCache {

    // 数据页的大小
    int PAGE_SIZE = 1 << 13;

    int newPage(byte[] initData);
    Page getPage(int pgno) throws Exception;
    void close();
    void release(Page page);

    void truncateByBgno(int maxPgno);
    int getPageNumber();
    void flushPage(Page pg);

    static PageCacheImpl create(String path, long memory) {
        File f = new File(path + PageCacheImpl.DB_SUFFIX);

        try {
            if (!f.createNewFile()) {
                Panic.panic(Error.FileExistsException);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (!f.canRead() ||  !f.canWrite()) {
            Panic.panic(Error.FileCannotRWException);
        }

        RandomAccessFile file = null;
        FileChannel channel = null;
        try {
            file = new RandomAccessFile(f, "rw");
            channel = file.getChannel();
        } catch (FileNotFoundException e) {
            Panic.panic(e);
        }
        return new PageCacheImpl(file, channel, (int)memory / PAGE_SIZE);
    }

    static PageCacheImpl open(String path, long memory) {
        File f = new File(path+PageCacheImpl.DB_SUFFIX);
        if(!f.exists()) {
            Panic.panic(Error.FileNotExistsException);
        }
        if(!f.canRead() || !f.canWrite()) {
            Panic.panic(Error.FileCannotRWException);
        }

        FileChannel fc = null;
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(f, "rw");
            fc = raf.getChannel();
        } catch (FileNotFoundException e) {
            Panic.panic(e);
        }
        return new PageCacheImpl(raf, fc, (int)memory/PAGE_SIZE);
    }
}
